package com.sap.apitest2.deprecated.service;

import java.io.ByteArrayOutputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Response;

import com.sap.apitest2.common.HTTPSender;
import com.sap.apitest2.deprecated.process.CaseProcess;
import com.sap.apitest2.deprecated.process.CatalogProcess;
import com.sap.apitest2.deprecated.process.EntityProcess;
import com.sap.apitest2.deprecated.process.ParamProcess;
import com.sap.apitest2.deprecated.process.ProfileProcess;
import com.sap.apitest2.deprecated.process.ResultProcess;
import com.sap.apitest2.deprecated.process.StepProcess;
import com.sap.apitest2.deprecated.process.SubCaseProcess;
import com.sap.apitest2.entity.Case;
import com.sap.apitest2.entity.Catalog;
import com.sap.apitest2.entity.ExecuteReturn;
import com.sap.apitest2.entity.Metadata;
import com.sap.apitest2.entity.Param;
import com.sap.apitest2.entity.Profile;
import com.sap.apitest2.entity.ProfileGroup;
import com.sap.apitest2.entity.Result;
import com.sap.apitest2.entity.Server;
import com.sap.apitest2.entity.Step;
import com.sap.apitest2.entity.Subcase;




@Path("/")
public class CommonService extends AbstractService {
	
	public static void main(String[] args){
		String host = "http://ldcie1f.wdf.sap.corp:50015";
		System.out.println(host.substring(0, host.lastIndexOf(":")));//host.substring(host.lastIndexOf(":")+1,host.length()));
	}
	
	protected EntityProcess entityProcess=new EntityProcess();
	protected CatalogProcess catalogProcess=new CatalogProcess();
	protected CaseProcess caseProcess=new CaseProcess();
	protected SubCaseProcess subCaseProcess=new SubCaseProcess();	
	protected StepProcess stepProcess=new StepProcess();		
	protected ResultProcess resultProcess=new ResultProcess();	
	protected ParamProcess paramProcess=new ParamProcess();
	protected ProfileProcess profileProcess=new ProfileProcess();

	@Path(ACTION_METADATA+"")
	@GET
	@Produces("application/json")
	public  Metadata getMetadata(){
		System.out.println("************* getMetadata start! ");
		Metadata metadata=new Metadata();;
		try{
/*			Collection<AbstractEntity> servers = catalogProcess.getEntities(Server.class.getName());
			if(servers!=null){
				List<Server> sl = new ArrayList<Server>();
				for(AbstractEntity server : servers){
					sl.add((Server)server);
				}
				metadata.setServers(sl);
			}*/
			metadata.setServers(this.getServers());
/*			Collection<AbstractEntity> profiles = catalogProcess.getEntities(Profile.class.getName());
			if(profiles!=null){
				List<Profile> pl = new ArrayList<Profile>();
				for(AbstractEntity profile : profiles){
					pl.add((Profile)profile);
				}
				metadata.setProfiles(pl);
			}*/
			metadata.setProfiles(this.getProfiles());
/*			Collection<AbstractEntity> profilegroups = entityProcess.getEntities(ProfileGroup.class.getName());
			if(profilegroups!=null){
				List<ProfileGroup> pl = new ArrayList<ProfileGroup>();
				for(AbstractEntity profile : profilegroups){
					pl.add((ProfileGroup)profile);
				}
				metadata.setProfilegroups(pl);
			}*/
			metadata.setProfilegroups(this.getProfileGroups());
			//Collection<AbstractEntity> profiles = catalogProcess.getEntities(Profile.class.getName()));
		}
		catch(Exception ex){
			this.LogException(ex);
		}
		System.out.println("************* getMetadata end! "+metadata);
		return metadata;
	}
/*	public  Collection<Object> getMetadata(@PathParam("id") long id){
		System.out.println("************* getMetadata start! "+id);
		List metadata=new ArrayList();;
		try{
			metadata.addAll(catalogProcess.getEntities(Server.class.getName()));
			metadata.addAll(catalogProcess.getEntities(Profile.class.getName()));
		}
		catch(Exception ex){
			this.LogException(ex);
		}
		System.out.println("************* getMetadata end! "+metadata);
		return metadata;
	}*/
	
	@Path(ACTION_SERVERS)
	@GET
	@Produces("application/json")
	public  Collection<Server> getServers(){
		System.out.println("************* getServers start! ");
		List<Server> servers=null;
		try{
			servers=catalogProcess.getEntities(Server.class.getName());
			System.out.println("get Servers "+servers.size());
		}
		catch(Exception ex){
			this.LogException(ex);
		}
		System.out.println("************* getServers end! "+servers);
		return servers;
	}
	@Path(ACTION_SERVER+"/{id:\\d+}")
	@GET
	@Produces("application/json")
	public  Server getServer(@PathParam("id") long id){
		System.out.println("************* getServer start! "+id);
		Server server = null;
		try{
			server=catalogProcess.getEntity(Server.class, id);
		}
		catch(Exception ex){
			this.LogException(ex);
		}
		System.out.println("************* getServer end! "+server);
		return server;
	}
	@Path(ACTION_SAVESERVER+"/{id:\\d+}")
	@PUT
	@Consumes("application/json")
	@Produces("application/json")
	public  ExecuteReturn  saveServer(Server entity){
		System.out.println("************* saveServer start! "+entity);
		ExecuteReturn result=new ExecuteReturn();
		try{
			System.out.println("input name "+entity.getName());
			catalogProcess.saveEntity(entity);
			result.setSuccess(true);
			result.setServer(entity);
		}
		catch(Exception ex){
			this.LogException(ex);
			result.setSuccess(false);
			result.setMsg("Save Server Failed!");
		}
		System.out.println("************* saveServer end! "+result);
		return result;
	}
	@Path(ACTION_REMOVESERVER+"/{id:\\d+}")
	@DELETE
	@Consumes("application/json")
	@Produces("application/json")
	public  ExecuteReturn  removeServer(@PathParam("id") long id){
		System.out.println("************* removeServer start! "+id);
		ExecuteReturn result=new ExecuteReturn();
		try{
			Server entity = new Server();
			entity.setId(id);
			catalogProcess.removeEntity(entity);
			result.setSuccess(true);
			
			//TODO: Remove all children.

		}
		catch(Exception ex){
			this.LogException(ex);
			result.setSuccess(false);
			result.setMsg("Remove Server Failed!");
		}
		System.out.println("************* removeServer end! "+result);
		return result;
	}
	
	@Path(ACTION_PROFILES)
	@GET
	@Produces("application/json")
	public  Collection<Profile> getProfiles(){
		System.out.println("************* getProfiles start! ");
		Collection<Profile> profiles=null;
		try{
			profiles=profileProcess.getEntities(Profile.class.getName());
			System.out.println("get Profiles "+profiles.size());
		}
		catch(Exception ex){
			this.LogException(ex);
		}
		System.out.println("************* getProfiles end! "+profiles);
		return profiles;
	}
	public  Collection<Profile> getProfilesByGroup(long id){
		System.out.println("************* getProfilesByGroup start! "+id);
		Collection<Profile> profiles=null;
		try{
			profiles=profileProcess.getProfileByGroup(id);
			System.out.println("getProfilesByGroup "+profiles.size());
		}
		catch(Exception ex){
			this.LogException(ex);
		}
		System.out.println("************* getProfilesByGroup end! "+profiles);
		return profiles;
	}
	public  Collection<Profile> getProfilesByServer(long id){
		System.out.println("************* getProfilesByServer start! "+id);
		Collection<Profile> profiles=null;
		try{
			profiles=profileProcess.getProfileByServer(id);
			System.out.println("getProfilesByServer "+profiles.size());
		}
		catch(Exception ex){
			this.LogException(ex);
		}
		System.out.println("************* getProfilesByServer end! "+profiles);
		return profiles;
	}
	@Path(ACTION_PROFILE+"/{id:\\d+}")
	@GET
	@Produces("application/json")
	public  Profile getProfile(@PathParam("id") long id){
		System.out.println("************* getProfile start! "+id);
		Profile profile = null;
		try{
			profile = profileProcess.getEntity(Profile.class, id);
			
			//System.out.println("get Profiles "+profiles.size());
		}
		catch(Exception ex){
			this.LogException(ex);
		}
		System.out.println("************* getProfile end! "+profile);
		return profile;
	}
	@Path(ACTION_SAVEPROFILE+"/{id:\\d+}")
	@PUT
	@Consumes("application/json")
	@Produces("application/json")
	public  ExecuteReturn  saveProfile(Profile entity){
		System.out.println("************* saveProfile start! "+entity);
		ExecuteReturn result=new ExecuteReturn();
		try{
			//System.out.println("input name "+entity.getName());
			
			if(entity.getServers()!=null && entity.getServers().size()>0){
				System.out.println("server size "+entity.getServers().size());
				//Long origId = entity.getId();
				for(Server server : entity.getServers()){
					if(server==null) continue;
					
					
					if(server.getId()!=null && server.getId()>0 && server.getHostUrl()==null){
						//skip
					}
					else{
						this.saveServer(server);
					}
					Profile profile =new Profile();
					profile.acceptValue(entity);
					profile.setServerId(server.getId());
					profile.setName(entity.getName()+(server.getName()!=null?"_in_"+server.getName():""));
					catalogProcess.saveEntity(profile);
				}
			}
			else{
				catalogProcess.saveEntity(entity);
			}
			
			result.setSuccess(true);
			result.setProfile(entity);
		}
		catch(Exception ex){
			this.LogException(ex);
			result.setSuccess(false);
			result.setMsg("Save Profile Failed!");
		}
		System.out.println("************* saveProfile end! "+result);
		return result;
	}
	@Path(ACTION_REMOVEPROFILE+"/{id:\\d+}")
	@DELETE
	@Consumes("application/json")
	@Produces("application/json")
	public  ExecuteReturn  removeProfile(@PathParam("id") long id){
		System.out.println("************* removeProfile start! "+id);
		ExecuteReturn result=new ExecuteReturn();
		try{
			Profile entity=new Profile();
			entity.setId(id);
			//System.out.println("input name "+entity.getName());
			catalogProcess.removeEntity(entity);
			result.setSuccess(true);
			
			//TODO: Remove all children.

		}
		catch(Exception ex){
			this.LogException(ex);
			result.setSuccess(false);
			result.setMsg("Remove Profile Failed!");
		}
		System.out.println("************* removeProfile end! "+result);
		return result;
	}
	@Path(ACTION_PROFILEGROUPS)
	@GET
	@Produces("application/json")
	public  Collection<ProfileGroup> getProfileGroups(){
		System.out.println("************* getProfileGroups start! ");
		List<ProfileGroup> groups=null;
		try{
			groups=entityProcess.getEntities(ProfileGroup.class.getName());
			System.out.println("get Profiles "+groups.size());
			for(ProfileGroup group : groups){
				group.setProfiles(this.getProfilesByGroup(group.getId()));
			}
		}
		catch(Exception ex){
			this.LogException(ex);
		}
		System.out.println("************* getProfileGroups end! "+groups);
		return groups;
	}
	@Path(ACTION_PROFILEGROUP+"/{id:\\d+}")
	@GET
	@Produces("application/json")
	public  ProfileGroup getProfileGroup(@PathParam("id") long id){
		System.out.println("************* getProfileGroup start! "+id);
		ProfileGroup group = null;
		try{
			group=entityProcess.getEntity(ProfileGroup.class, id);
			
			group.setProfiles(this.getProfilesByGroup(group.getId()));
			//System.out.println("get Profiles "+profiles.size());
		}
		catch(Exception ex){
			this.LogException(ex);
		}
		System.out.println("************* getProfileGroup end! "+group);
		return group;
	}
	@Path(ACTION_SAVEPROFILEGROUP+"/{id:\\d+}")
	@PUT
	@Consumes("application/json")
	@Produces("application/json")
	public  ExecuteReturn  saveProfileGroup(ProfileGroup entity){
		System.out.println("************* saveProfileGroup start! "+entity);
		ExecuteReturn result=new ExecuteReturn();
		try{
			entityProcess.saveEntity(entity);
				
			result.setSuccess(true);
			result.setProfilegroup(entity);
		}
		catch(Exception ex){
			this.LogException(ex);
			result.setSuccess(false);
			result.setMsg("Save ProfileGroup Failed!");
		}
		System.out.println("************* saveProfileGroup end! "+result);
		return result;
	}
	@Path(ACTION_REMOVEPROFILEGROUP+"/{id:\\d+}")
	@DELETE
	@Consumes("application/json")
	@Produces("application/json")
	public  ExecuteReturn  removeProfileGroup(@PathParam("id") long id){
		System.out.println("************* removeProfileGroup start! "+id);
		ExecuteReturn result=new ExecuteReturn();
		try{
			ProfileGroup entity=new ProfileGroup();
			entity.setId(id);
			
			entityProcess.removeEntity(entity);
			result.setSuccess(true);
			
			//TODO: Remove all children.

		}
		catch(Exception ex){
			this.LogException(ex);
			result.setSuccess(false);
			result.setMsg("Remove Profile Group Failed!");
		}
		System.out.println("************* removeProfileGroup end! "+result);
		return result;
	}
	
	
	
	@Path(ACTION_CATALOGS+"/{id:\\d+}")//"/bpccatalogs/{id:\\d+}"
	@GET
	@Produces("application/json")
	public  Collection<Catalog> getCatalogs(@PathParam("id") long id){
		System.out.println("************* getCatalogs start! "+id);
		List<Catalog> catalogs=null;
		try{
			catalogs=catalogProcess.getEntities(Catalog.class.getName());
			System.out.println("get catalogs "+catalogs.size());
		}
		catch(Exception ex){
			this.LogException(ex);
		}
		System.out.println("************* getCatalogs end! "+catalogs);
		return catalogs;
	}
	@Path(ACTION_CATALOG+"/{id:\\d+}")//"/bpccatalog/{id:\\d+}"
	@GET
	@Produces("application/json")
	public  Catalog getCatalog(@PathParam("id") long id){
		System.out.println("************* getCatalog start! "+id);
		Catalog catalog=null;
		try{
			//org.datanucleus.api.jpa.PersistenceProviderImpl p=null;
			catalog=catalogProcess.getEntity(Catalog.class, id);
			//System.out.println("catalog "+catalog+"  "+id);
		}
		catch(Exception ex){
			this.LogException(ex);
		}
		System.out.println("************* getCatalog end! "+catalog);
		return catalog;
	}
	
	@Path(ACTION_SAVECATALOG+"/{id:\\d+}")//"/bpcsavecatalog"
	@PUT
	@Consumes("application/json")
	@Produces("application/json")
	public  ExecuteReturn  saveCatalog(Catalog entity){
		System.out.println("************* saveCatalog start! "+entity);
		ExecuteReturn result=new ExecuteReturn();
		try{
			//System.out.println("input name "+entity.getName());
			if(entity.getType()==null) 
				entity.setType(1);
			
			catalogProcess.saveEntity(entity);
			
			
			result.setSuccess(true);
			result.setCatalog(entity);
		}
		catch(Exception ex){
			this.LogException(ex);
			result.setSuccess(false);
			result.setMsg("Save Catalog Failed!");
		}
		System.out.println("************* saveCatalog end! "+result);
		return result;
	}
	
	@Path(ACTION_REMOVECATALOG+"/{id:\\d+}")//"/bpcremovecatalog/{id:\\d+}"
	@DELETE
	@Consumes("application/json")
	@Produces("application/json")
	public  ExecuteReturn  removeCatalog(@PathParam("id") long id){
		System.out.println("************* removeCatalog start! "+id);
		ExecuteReturn result=new ExecuteReturn();
		try{
			Collection<Case> cases=this.getCases(id);
			if(cases!=null){
				for(Case acase:cases){
					this.removeCase(acase.getId());
				}
			}
			
			Catalog entity=catalogProcess.getEntity(Catalog.class, id);
			
			System.out.println("remove id "+entity.getId());
			catalogProcess.removeEntity(entity);
			result.setSuccess(true);
		}
		catch(Exception ex){
			this.LogException(ex);
			result.setSuccess(false);
			result.setMsg("Remove Catalog Failed!");
		}
		System.out.println("************* removeCatalog end! "+result);
		return result;
	}

	
	@Path(ACTION_CASESTREE)
	@GET
	@Produces("application/json")
	public  List<Catalog> getCaseTree(){
		
		System.out.println("******  getCaseTree start!");
		
		List<Catalog> Catalogs=null;
		try{
			Catalogs=caseProcess.getEntities(Catalog.class.getName());
			if(Catalogs!=null){
				System.out.println("get catalogs "+Catalogs.size());
				for(Catalog catalog:Catalogs){
					System.out.println("get catalog "+catalog.getId()+" name "+catalog.getName());
					catalog.setCases(caseProcess.getCasesByCatalog(catalog.getId()));
					if(catalog.getCases()!=null)
						System.out.println("get cases "+catalog.getCases().size());
					
				}
			}
		}
		catch(Exception ex){
			this.LogException(ex);
		}
		System.out.println("******  getCaseTree end!");
		return Catalogs;
	}
/*	@Path(ACTION_CASESTREE)
	@GET
	@Produces("application/json")
	public  Map<String, String> getCaseTree(){
		Map<String, String> temp=new HashMap<String, String>();
		temp.put("id", "1");
		return temp;
	}*/
/*	@Path(ACTION_SAVECASE)
	@POST
	@Consumes("application/json")
	@Produces("application/json")
	public  ExecuteReturn  createCase(Case entity){
		return saveCase(entity);
	}*/
	
	
	@Path(ACTION_SAVECASE+"/{id:\\d+}")
	@PUT
	@Consumes("application/json")
	@Produces("application/json")
	public  ExecuteReturn  saveCase(Case entity){
		System.out.println("************* saveCase start! "+entity);
		
		ExecuteReturn	result=new ExecuteReturn();
		try{
			System.out.println("input case key "+entity.getId());

			caseProcess.saveEntity(entity);
			this.saveCaseDetails(entity);
			
			
			System.out.println("entering setCase");
			entity.setSteps(stepProcess.getStepsByCase(entity.getId()));
			result.setCase(entity);
			result.setSuccess(true);
			
		}
		catch(Exception ex){
			this.LogException(ex);
			result.setSuccess(false);
			result.setMsg(ex.toString());
			//result.setMsg("Save Case Failed!");
		}
		System.out.println("************* saveCase end! "+entity);
		return result;
	}
	protected void saveCaseDetails(Case entity)throws Exception{
		if(entity.getSteps()!=null){
			System.out.println("Steps "+entity.getSteps().size());
		
			for(Step step:entity.getSteps()){
				if (step.getName() == null)
					return;
				System.out.println("request "+step.getRequest().toString());
				System.out.println("desc "+step.getDesc());
				step.setCaseId(entity.getId());
			}				
			this.stepProcess.saveSteps(entity.getId(), entity.getSteps());

		}
		if(entity.getSubCases()!=null){
			System.out.println("SubCases "+ entity.getSubCases().size());
			for(Subcase subcase:entity.getSubCases()){
				
				subcase.setCaseId(entity.getId());					
			}
			this.subCaseProcess.saveSubCases(entity.getId(), entity.getSubCases());
			for(Subcase subcase:entity.getSubCases()){
				this.saveSubcaseDetails(subcase);
			}
		}
	}
	
	
	@Path(ACTION_SAVESUBCASE)
	@POST
	@Consumes("application/json")
	public  Response  copyCase(Case entity){
		System.out.println("************* copyCase start! "+entity);
		try{
			String newname=entity.getName();
			Case tocopy=caseProcess.getEntity(Case.class, entity.getId());
			System.out.println("case to copy "+entity.getName());
			tocopy.setName(newname);
			tocopy.setId(0l);
			
			caseProcess.saveEntity(entity);
		}
		catch(Exception ex){
			this.LogException(ex);
			return Response.serverError().build();
		}
		Response resp= Response.ok().build();
		System.out.println("************* copyCase end! "+resp);
		return resp;
	}
	@Path(ACTION_CASES+"/{id:\\d+}")
	@GET
	@Produces("application/json")
	public  Collection<Case> getCases(@PathParam("id") long id){
		System.out.println("************* getCases start! "+id);
		List<Case> Cases=null;
		try{
			Cases=caseProcess.getEntities(Case.class.getName());
			System.out.println("get Cases "+Cases.size());
		}
		catch(Exception ex){
			this.LogException(ex);
		}
		System.out.println("************* getCases end! "+Cases);
		return Cases;
	}
	
	@Path(ACTION_CASE+"/{id:\\d+}")
	@GET
	@Produces("application/json")
	public  Case getCase(@PathParam("id") long id){
		System.out.println("************ getCase start!"+id);
		Case Case=null;
		try{
			//org.datanucleus.api.jpa.PersistenceProviderImpl p=null;
			Case=caseProcess.getEntity(Case.class, id);
			System.out.println("Case "+Case+"  "+id);
			if(Case!=null){
				Case.setSteps(this.getSteps(id));
				Case.setSubCases(this.getSubCases(id));
			}
		}
		catch(Exception ex){
			this.LogException(ex);
		}
		System.out.println("************ getCase end!"+Case);
		return Case;
	}
	
	@Path(ACTION_CASEDETAIL+"/{id:\\d+}")
	@GET
	@Produces("application/json")
	public  Case getCaseDetail(@PathParam("id") long id){
		System.out.println("************ getCaseDetail start!"+id);
		Case Case=null;
		try{
			//org.datanucleus.api.jpa.PersistenceProviderImpl p=null;
			Case=caseProcess.getEntity(Case.class, id);
			System.out.println("Case "+Case+"  "+id);
			
			if(Case!=null){
				Case.setSubCases(subCaseProcess.getSubCasesByCase(Case.getId()));
				Case.setSteps(stepProcess.getStepsByCase(Case.getId()));
			}
			
		}
		catch(Exception ex){
			this.LogException(ex);
		}
		System.out.println("************ getCaseDetail end!"+Case);
		return Case;
	}
	@Path(ACTION_CASESTATUS+"/{id:\\d+}")
	@GET
	@Produces("application/json")
	public  Case getCaseStatus(@PathParam("id") long id){
		System.out.println("************ getCaseStatus start!"+id);
		Case Case=null;
		try{
			//org.datanucleus.api.jpa.PersistenceProviderImpl p=null;
			Case=caseProcess.getEntity(Case.class, id);
			System.out.println("Case "+Case+"  "+id);
			
			if(Case!=null){
				Collection<Subcase> subcases=subCaseProcess.getSubCasesByCase(Case.getId());
				if(subcases!=null){
					Iterator<Subcase> it=subcases.iterator();
					while(it.hasNext()){
						Subcase subcase=it.next();
						subcase.setStatus(
								resultProcess.getRunResultsBySubCase(subcase.getId())
								);
					}
				}
				Case.setSubCases(subcases);				
			}
			
		}
		catch(Exception ex){
			this.LogException(ex);
		}
		System.out.println("************ getCaseStatus end!"+Case);
		return Case;
	}

	@Path(ACTION_REMOVECASE+"/{id:\\d+}")
	@DELETE
	@Consumes("application/json")
	@Produces("application/json")
	public  ExecuteReturn  removeCase(@PathParam("id") long id){
		System.out.println("************ removeCase start!"+id);
		ExecuteReturn result=new ExecuteReturn();
		try{
			
			Collection<Step> steps=this.getSteps(id);
			if(steps!=null){
				for(Step step:steps){
					this.removeStep(step.getId());
				}
			}
			Collection<Subcase> subcases=this.getSubCases(id);
			if(subcases!=null){
				for(Subcase subcase:subcases){
					this.removeSubCase(subcase.getId());
				}
			}
			
			Case entity=new Case();
			entity.setId(id);
			
			System.out.println("remove id "+entity.getId());
			caseProcess.removeEntity(entity);
			result.setSuccess(true);
			
		}
		catch(Exception ex){
			this.LogException(ex);
			result.setSuccess(false);
			result.setMsg("Remove Case Failed!");
		}
		System.out.println("************ removeCase end!"+result);
		return result;
	}
	
	
	//+++++++++++++++++++++++subcase
	@Path(ACTION_SAVESUBCASE+"/{id:\\d+}")
	@PUT
	@Consumes("application/json")
	@Produces("application/json")
	public  ExecuteReturn  saveSubCase(Subcase entity){
		System.out.println("************ saveSubCase start!"+entity);
		ExecuteReturn result=new ExecuteReturn();
		try{
			//System.out.println("input name "+entity.getName());
			subCaseProcess.saveEntity(entity);
			result.setMsg("Save SubCase Successfully!");
			this.saveSubcaseDetails(entity);			
			
			result.setSuccess(true);
			result.setSubcase(entity);
		}
		catch(Exception ex){
			this.LogException(ex);
			result.setSuccess(false);
			result.setMsg("Save SubCase Failed!");
		}
		System.out.println("************ saveSubCase end!"+result);
		return result;
	}
	protected  void  saveSubcaseDetails(Subcase entity)throws Exception{
		System.out.println("Params "+entity.getParams());
		if(entity.getParams()!=null){
			System.out.println("Params "+entity.getParams().size());
			for(Param param:entity.getParams()){
				param.setSubCaseId(entity.getId());
				//this.saveParam(param);
			}
			this.paramProcess.saveParams(entity.getId(), entity.getParams());
		}
	}
	//++++++++++++++++PARAM++++++++++++++++++++
	@Path(ACTION_PARAMETERS+"/{id:\\d+}")
	@GET
	@Produces("application/json")
	public  Collection<Param> getParams(@PathParam("id") long id){
		System.out.println("************ getParams start!"+id);
		Collection<Param> params=null;
		try{
			params=paramProcess.getParamsBySubcase(id);
			System.out.println("get params "+params.size());
		}
		catch(Exception ex){
			this.LogException(ex);
		}
		System.out.println("************ getParams end!"+params);
		return params;
	}
	
	@Path(ACTION_SAVEPARAMETER+"/{id:\\d+}")
	@PUT
	@Consumes("application/json")
	@Produces("application/json")
	public  ExecuteReturn  saveParam(Param entity){
		System.out.println("************ saveParam start!"+entity);
		ExecuteReturn result=new ExecuteReturn();
		try{
			//System.out.println("input name "+entity.getName());
			subCaseProcess.saveEntity(entity);
			
			result.setSuccess(true);
			result.setParam(entity);
		}
		catch(Exception ex){
			this.LogException(ex);
			result.setSuccess(false);
			result.setMsg("Save Param Failed!");
		}
		System.out.println("************ saveParam end!"+result);
		return result;
	}
	@Path(ACTION_REMOVEPARAMETER+"/{id:\\d+}")
	@DELETE
	@Consumes("application/json")
	@Produces("application/json")
	public  ExecuteReturn  removeParam(@PathParam("id") long id){
		System.out.println("************ removeParam start!"+id);
		ExecuteReturn result=new ExecuteReturn();
		try{
			Param entity=new Param();
			entity.setId(id);
			subCaseProcess.removeEntity(entity);
			
			result.setSuccess(true);
			result.setParam(entity);
		}
		catch(Exception ex){
			this.LogException(ex);
			result.setSuccess(false);
			result.setMsg("Save Param Failed!");
		}

		System.out.println("************ removeParam end!"+result);
		return result;
	}
	
	@Path(ACTION_SUBCASES+"/{id:\\d+}")
	@GET
	@Produces("application/json")
	public  Collection<Subcase> getSubCases(@PathParam("id") long id){
		System.out.println("************ getSubCases start!"+id);
		Collection<Subcase> SubCases=null;
		try{
			SubCases=subCaseProcess.getSubCasesByCase(id);
			System.out.println("get SubCases "+SubCases.size());
			if(SubCases!=null){
				for(Subcase subcase : SubCases){
					subcase.setParams(this.getParams(subcase.getId()));
				}
			}
		}
		catch(Exception ex){
			this.LogException(ex);
		}
		System.out.println("************ getSubCases end!"+id);
		return SubCases;
	}
	
	@Path(ACTION_SUBCASE+"/{id:\\d+}")
	@GET
	@Produces("application/json")
	public  Subcase getSubCase(@PathParam("id") long id){
		System.out.println("************ getSubCase start!"+id);
		Subcase SubCase=null;
		try{
			//org.datanucleus.api.jpa.PersistenceProviderImpl p=null;
			SubCase=subCaseProcess.getEntity(Subcase.class, id);
			System.out.println("SubCase "+SubCase+"  "+id);
		}
		catch(Exception ex){
			this.LogException(ex);
		}
		System.out.println("************ getSubCase end!"+SubCase);
		return SubCase;
	}
	@Path(ACTION_REMOVESUBCASE+"/{id:\\d+}")
	@DELETE
	@Consumes("application/json")
	@Produces("application/json")
	public  ExecuteReturn  removeSubCase(@PathParam("id") long id){
		System.out.println("************ removeSubCase start!"+id);
		ExecuteReturn result=new ExecuteReturn();
		try{
			Collection<Param> params = this.getParams(id);
			if(params!=null){
				for(Param param:params){
					this.removeParam(param.getId());
				}
			}
			
			Subcase entity=new Subcase();
			entity.setId(id);
			System.out.println("remove id "+entity.getId());
			subCaseProcess.removeEntity(entity);
		}
		catch(Exception ex){
			this.LogException(ex);
			
		}
		System.out.println("************ removeSubCase end!"+result);
		return result;
	}
	//+++++++++++++++Step+++++++++++++++++
	@Path(ACTION_STEPS+"/{id:\\d+}")
	@GET
	@Produces("application/json")
	public  Collection<Step> getSteps(@PathParam("id") long id){
		System.out.println("************ getSteps start!"+id);
		Collection<Step> Steps=null;
		try{
			Steps=stepProcess.getStepsByCase(id);
			System.out.println("get Steps "+Steps.size());
		}
		catch(Exception ex){
			this.LogException(ex);
		}
		System.out.println("************ getSteps end!"+Steps);
		return Steps;
	}
	
	
	@Path(ACTION_STEP+"/{id:\\d+}")
	@GET
	@Produces("application/json")
	public  Step getStep(@PathParam("id") long id){
		System.out.println("************ getStep start!"+id);
		Step Step=null;
		try{
			//org.datanucleus.api.jpa.PersistenceProviderImpl p=null;
			Step=stepProcess.getEntity(Step.class, id);
			System.out.println("Step "+Step+"  "+id);
		}
		catch(Exception ex){
			this.LogException(ex);
		}
		System.out.println("************ getStep end!"+Step);
		return Step;
	}
	@Path(ACTION_SAVESTEP+"/{id:\\d+}")
	@PUT
	@Consumes("application/json")
	@Produces("application/json")
	public  ExecuteReturn  saveStep(Step entity){
		System.out.println("************ saveStep start!"+entity);
		ExecuteReturn result=new ExecuteReturn();
		try{
			System.out.println("input name "+entity.getName());
			stepProcess.saveEntity(entity);
			result.setSuccess(true);
			result.setStep(entity);
		}
		catch(Exception ex){
			this.LogException(ex);
			result.setSuccess(false);
			result.setMsg("Save Step Failed!");
		}
		System.out.println("************ saveStep end!"+result);
		return result;
	}
	@Path(ACTION_REMOVESTEP+"/{id:\\d+}")
	@DELETE
	@Consumes("application/json")
	@Produces("application/json")
	public  ExecuteReturn  removeStep(@PathParam("id") long id){
		System.out.println("************ saveStep start!"+id);
		ExecuteReturn result=new ExecuteReturn();
		try{
			Step entity=new Step();
			entity.setId(id);
			System.out.println("remove id "+entity.getId());
			stepProcess.removeEntity(entity);
			result.setSuccess(true);
			
			//TODO: Remove all children.
			
		}
		catch(Exception ex){
			this.LogException(ex);
			result.setSuccess(false);
			result.setMsg("Remove Case Failed!");
		}
		System.out.println("************ saveStep end!"+result);
		return result;
	}
	//++++++++++++++++test run
	@Path(ACTION_TESTSRUN+"/{caseid:\\d+}")
	@POST
	@Consumes("application/json")
	@Produces("application/json")
	public  Collection<Result>  testsRun(@PathParam("caseid") long caseid){
		System.out.println("************ Multiple Tests Run start! caseid "+caseid);
		Collection<Result> results = new ArrayList<Result>();
		if(caseid>0){
			Case tcase = this.getCase(caseid);
			Collection<Profile> profiles = this.getProfilesByGroup(tcase.getProfilegroupId());
			
			for(Profile profile : profiles){
				results.addAll(testsRun(caseid, 0, profile.getId()));
			}
			
		}
		System.out.println("************ Multiple Tests Run end! "+results);
		return results;
	}
	
	//++++++++++++++++test run
	@Path(ACTION_TESTSRUN+"/{caseid:\\d+}/{subcaseid:\\d+}/{profileid:\\d+}")
	@POST
	@Consumes("application/json")
	@Produces("application/json")
	public  Collection<Result>  testsRun(@PathParam("caseid") long caseid
				, @PathParam("subcaseid") long subcaseid
				, @PathParam("profileid") long profileid){
		System.out.println("************ Multiple Tests Run start! caseid "+caseid+" subcaseid "+subcaseid+" profileid "+profileid);
		Collection<Result> results = new ArrayList<Result>();
		try{
			System.out.println("run case "+caseid);
			if(caseid==0){
				Result result = new Result();
				result.setStatus(-1);
				result.setResponse("Error param!");
				results.add(result);
				return results;
			}
	
			if(subcaseid>0){
				
				results.addAll(testRun(subcaseid, profileid));
	
			}
			else{
				Collection<Subcase> subcases = this.getSubCases(caseid);
				if(subcases!=null){
					for(Subcase scase : subcases){
						results.addAll(testRun(scase.getId(), profileid));
					}
				}
			}
		}
		catch(Exception ex){
			this.LogException(ex);
			Result result = new Result();
			result.setStatus(-1);
			result.setResponse(ex.getMessage());
			return results;
		}
		System.out.println("************ testsRun end! "+results);
		return results;
	}
	
	@Path(ACTION_TESTRUN+"/{subcaseid:\\d+}")
	@POST
	@Consumes("application/json")
	@Produces("application/json")
	public  Collection<Result>  testRun(@PathParam("subcaseid") long subcaseid){
		System.out.println("************ Single Test Run start! "+subcaseid);
		Collection<Result> results = new ArrayList<Result>();
		if(subcaseid>0){
			Subcase scase = this.getSubCase(subcaseid);
			
			Case tcase = this.getCase(scase.getCaseId());
			
			Collection<Profile> profiles = this.getProfilesByGroup(tcase.getProfilegroupId());
			
			for(Profile profile : profiles){
				results.addAll(testRun(subcaseid, profile.getId()));
			}
		}
		System.out.println("************ Single Test Run start! "+subcaseid);
		return results;
	}
	
	@Path(ACTION_TESTRUN+"/{subcaseid:\\d+}/{profileid:\\d+}")
	@POST
	@Consumes("application/json")
	@Produces("application/json")
	public  Collection<Result>  testRun(@PathParam("subcaseid") long subcaseid
			, @PathParam("profileid") long profileid){
		System.out.println("************ Single Test Run start! "+subcaseid+"  "+profileid);
		Collection<Result> results = new ArrayList<Result>();
		try{
			System.out.println("run Subcase "+subcaseid);
			if(profileid>0 && subcaseid>0){
			
				Subcase scase = this.getSubCase(subcaseid);
			
			
			/*String username = "wenjo";
			String password = "nbspace";
			String host = "http://ldcie1f.wdf.sap.corp";
			String port = "50015";*/
			
			
				Profile profile = this.getProfile(profileid);
				Server server = this.getServer(profile.getServerId());
				
				String username = profile.getUsername();
				String password = profile.getPassword();
				String host = server.getHostUrl();//"http://ldcie2f.wdf.sap.corp"
				host = host.substring(0, host.lastIndexOf(":"));
				String port = 
					server.getHostUrl()!=null?
							server.getHostUrl().substring(server.getHostUrl().lastIndexOf(":")+1,server.getHostUrl().length())
							:"50015";//50015
				
				
				System.out.println("username "+username);
				System.out.println("password "+password);
				System.out.println("host "+host);
				System.out.println("port "+port);
				
/*				username = "wenjo";
				password = "nbspace";
				host = "http://ldcie1f.wdf.sap.corp";
				port = "50015";*/
			
		
				Subcase subcase = this.getSubCase(subcaseid);
				
				//org.apache.http.conn.scheme.SocketFactory s=null;
				Collection<Param> params = this.getParams(subcaseid);
				
				
				Collection<Step> steps = this.getSteps(scase.getCaseId());
				if(steps!=null){
					for(Step step : steps){
						
						String targeturl = step.getUrl();
						if(targeturl==null || "".equals(targeturl)) 
							continue;
						System.out.println("url "+targeturl);
						targeturl.replaceAll("<%APPSET%>", profile.getAppset());		
						targeturl.replaceAll("<%APPL%>", profile.getApplication());
						
						String request_byte = step.getRequest();
						String request = null;
						//String request = step.getRequest();
						if (request_byte != null) request = request_byte.toString();
						if(request!=null){
							if(params!=null){
								for(Param param : params){
									System.out.println("param "+param.getName()+" "+param.getValue());
									if(param.getName()!=null && param.getValue()!=null) {
										request = request.replace("<%" + param.getName() + "%>", param.getValue().toString());
									}
								}
							}
						}
						System.out.println("request "+request);
						/*if(params!=null){
							for(Param param : params){
								System.out.println("param "+param.getName()+" "+param.getValue());
								if(param.getName()!=null && para
								\
								m.getValue()!=null)
									targeturl.replaceAll(param.getName(), param.getValue());								
							}
						}
						*/
						Result result = new Result();
						result.setExpectedResponse(step.getResponse());
						result.setDate(new Date());
						result.setStartTime(new Date());
						System.out.println("targeturl "+targeturl);
						HTTPSender sender = new HTTPSender(
								 targeturl//step.getUrl()//"/sap/bpcmodeling/workstatus/TRANS_QA_CLME104/Consolidation"
								,step.getFormat()//,"XML"
								,step.getMethod()//,"GET"
								,username
								,password
								,host
								,port
								,null
								,null
								);
						ByteArrayOutputStream out = new ByteArrayOutputStream();
						out.write(request.getBytes());
						System.out.println("1111111");
						sender.setHeader(step.getHeader());
						sender.setRequest(out);
						//org.apache.http.conn.scheme.SocketFactory s=null;
						System.out.println("2222222");
						sender.send();
						System.out.println("3333333");
						OutputStream res = sender.getResponse();
						result.setEndTime(new Date());
						
						int statusCode = sender.getStatusCode();
						
						System.out.println("statusCode "+statusCode);
						//byte[] resp=new byte[10240];
						//res.write(resp);
						result.setResponse(res.toString());
						//result.setResponse(res.write(arg0))
						result.setStatus(statusCode);
						result.setStepId(step.getId());
						result.setSubCaseId(subcase.getId());
						
						this.saveResult(result);
						
						
						results.add(result);
						
						
					}
					System.out.println("result "+ results.size());
				}				
				
				
			}
			
		}
		catch(Exception ex){
			this.LogException(ex);
			results = new ArrayList<Result>();
			Result result = new Result();
			result.setStatus(-1);
			result.setResponse(ex.getMessage());
			return results;
		}
		System.out.println("************ Single Test Run end! "+results);
		return results;
	}
	
	@Path(ACTION_LASTRESULTS+"/{caseid:\\d+}/{subcaseid:\\d+}")
	@GET
	@Produces("application/json")
	public  Collection<Result> getLastResults(@PathParam("caseid") long case_id, @PathParam("subcaseid") long subcase_id){
		System.out.println("************ getLastResults start! "+case_id);
		List<Result> Results=new ArrayList<Result>();
		try{
			if(subcase_id==0 && case_id!=0){
				Collection<Subcase> subcases=this.getSubCases(case_id);
				for(Subcase subcase : subcases){
					Results.addAll(getLastResultsFromSubCase(case_id, subcase.getId()));//(resultProcess.getRecentlyRunResultsByStep(subcase.getId()));
				}
			}
			else if(subcase_id!=0 && case_id==0){
				Subcase subcase = this.getSubCase(subcase_id);
				Results.addAll(getLastResultsFromSubCase(subcase.getCaseId(), subcase_id));//resultProcess.getRecentlyRunResultsByStep(subcase_id));
			
			}
			//Results=resultProcess.getEntities(Result.class.getName());
			System.out.println("getLastResults "+Results.size());
		}
		catch(Exception ex){
			this.LogException(ex);
		}
		System.out.println("************ getLastResults end! "+Results);
		return Results;
	}
	protected Collection<Result> getLastResultsFromSubCase(Long case_id, Long subcase_id){
		System.out.println("************ getLastResultsFromSubCase start! "+subcase_id);
		List<Result> Results=new ArrayList<Result>();
		try{
			Collection<Step>  steps = this.getSteps(case_id);
			for(Step step : steps){
				System.out.println("step.getId() "+step.getId());
				Results.add(resultProcess.getRecentlyRunResultsByStep(subcase_id, step.getId()));
			}
		}
		catch(Exception ex){
			this.LogException(ex);
		}
		System.out.println("************ getLastResultsFromSubCase end! "+subcase_id);
		return Results;
	}
	@Path(ACTION_ALLRESULTS+"/{caseid:\\d+}/{subcaseid:\\d+}")
	@GET
	@Produces("application/json")
	public  Collection<Result> getAllResults(@PathParam("caseid") long case_id, @PathParam("subcaseid") long subcase_id){
		System.out.println("************ getAllResults start! "+case_id);
		List<Result> Results=new ArrayList<Result>();
		try{
			if(subcase_id==0 && case_id!=0){
				Collection<Subcase> subcases=this.getSubCases(case_id);
				for(Subcase subcase : subcases){
					Results.addAll(getAllResultsFromSubCase(case_id, subcase.getId()));//(resultProcess.getRecentlyRunResultsByStep(subcase.getId()));
				}
			}
			else if(subcase_id!=0 && case_id==0){
				Subcase subcase = this.getSubCase(subcase_id);
				Results.addAll(getAllResultsFromSubCase(subcase.getCaseId(), subcase_id));//resultProcess.getRecentlyRunResultsByStep(subcase_id));
			}
			
			//Results=resultProcess.getEntities(Result.class.getName());
			//System.out.println("getAllResults end! "+Results.size());
		}
		catch(Exception ex){
			this.LogException(ex);
		}
		System.out.println("************ getAllResults end! "+Results);
		return Results;
	}	
	protected Collection<Result> getAllResultsFromSubCase(Long case_id, Long subcase_id){
		System.out.println("************ getAllResultsFromSubCase start! "+subcase_id);
		List<Result> Results=new ArrayList<Result>();
		try{
			Collection<Step>  steps = this.getSteps(case_id);
			for(Step step : steps){
				Results.add(resultProcess.getRecentlyRunResultsByStep(subcase_id, step.getId()));
			}
		}
		catch(Exception ex){
			this.LogException(ex);
		}
		System.out.println("************ getAllResultsFromSubCase end! "+subcase_id);
		return Results;
	}
	@Path(ACTION_SAVERESULT+"/{id:\\d+}")
	@PUT
	@Consumes("application/json")
	@Produces("application/json")
	public  ExecuteReturn  saveResult(Result entity){
		System.out.println("************ saveResult start! "+entity);
		ExecuteReturn result=new ExecuteReturn();
		try{
			System.out.println("input name "+entity.getName());
			resultProcess.saveEntity(entity);
			result.setSuccess(true);
			result.setResult(entity);
		}
		catch(Exception ex){
			this.LogException(ex);
			result.setSuccess(false);
			result.setMsg("Save Result Failed!");
		}
		System.out.println("************ saveResult end! "+result);
		return result;
	}
	
	
}
